#pragma once

#include "noncopyable.h"
#include "InetAddress.h"
#include "Callbacks.h"
#include "Buffer.h"

#include <memory>
#include <atomic>
#include <string>

class EventLoop;
class Channel;
class Socket;

//管理Tcp连接
class TcpConnection : noncopyable, public std::enable_shared_from_this<TcpConnection>
{
public:
    TcpConnection(EventLoop *loop,
                  const std::string &nameArg,
                  int socket,
                  const InetAddress &localAddr,
                  const InetAddress &peerAddr);
    ~TcpConnection();

    EventLoop *getLoop() const { return loop_; }
    const std::string &name() const { return name_; }
    const InetAddress &localAddress() const { return localAddr_; }
    const InetAddress &peerAddress() const { return peerAddr_; }

    // 是否连接成功
    bool connected() const { return state_ == kConnected; }

    // 发送数据
    void send(const std::string& message);
    // 关闭连接
    void shutdown();

    void setConnectionCallback(const ConnectionCallback &cb)
    {
        connectionCallback_ = cb;
    }
    void setMessageCallback(const MessageCallback &cb)
    {
        messageCallback_ = cb;
    }
    void setWriteCompleteCallback(const WriteCompleteCallback &cb)
    {
        writeCompleteCallback_ = cb;
    }
    void setHighWaterMarkCallback(const HighWaterMarkCallback &cb, size_t highWaterMark)
    {
        highWaterMarkCallback_ = cb;
        highWaterMark_ = highWaterMark;
    }
    void setCloseCallback(const CloseCallback &cb)
    {
        closeCallback_ = cb;
    }

    //连接建立
    void connectEstablished();
    //连接销毁
    void connectDestroyed();

    // 启动非活跃销毁，并定义了非活跃鉴定的时间
    void enableInactiveRelease(int sec);
    //启动非活跃销毁
    void enableInactiveReleaseInLoop(int sec);

    void refresh();
private:
    //删除该链接的非活跃销毁任务
    void cancelInactiveReleaseInLoop();

    //处理发生事件的函数
    void handleRead(Timestamp receiveTime);
    void handleWrite();
    void handleClose();
    void handleError();

    void setState(int stateE) {state_=stateE;}

    const char* stateToString() const;

    //loop线程中排队发送消息
    void sendInLoop(const void *message, size_t len);
    //loop线程中排队  关闭写连接
    void shutdownInLoop();

    enum StateE
    {
        kDisconnected,
        kConnecting,
        kConnected,
        kDisconnecting
    };
    EventLoop *loop_;
    const std::string name_;
    std::atomic_int state_;
    bool reading_;

    std::unique_ptr<Socket> socket_;   // 连接产生的套接字
    std::unique_ptr<Channel> channel_; // channel通道，封装要关心的事件

    const InetAddress localAddr_;
    const InetAddress peerAddr_;

    ConnectionCallback connectionCallback_; //连接回调。连接建立、销毁、强制关闭时都会调用该函数
    MessageCallback messageCallback_;             // 有读写消息时的回调
    WriteCompleteCallback writeCompleteCallback_; // 消息发送完成后的回调
    CloseCallback closeCallback_;
    HighWaterMarkCallback highWaterMarkCallback_;

    size_t highWaterMark_;
    bool enableInactiveRelease_; //标识是否启动非活跃销毁

    //应用层缓冲区
    Buffer inputBuffer_;    //接收缓冲区。write是从fd接收数据往buf写，read是从buf读取数据去处理
    Buffer outputBuffer_;   //发送缓冲区。write是将要发送的数据先写入buf，read是从buf读数据通过fd发送
};